<!doctype html>
<html lang="zh-CN">
<head>
	<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>通过WebRTC实现网页间文件传输 | Mike SU</title>
<meta property="og:title" content="通过WebRTC实现网页间文件传输 - Mike SU">
<meta property="og:type" content="article">
	
<meta property="article:published_time" content='2014-11-05T18:23:34&#43;08:00'>
	
	
<meta property="article:modified_time" content='2014-11-05T18:23:34&#43;08:00'>
	
<meta name="Keywords" content="">
<meta name="description" content="通过WebRTC实现网页间文件传输">
	
<meta name="author" content="Mike SU">
<meta property="og:url" content="https://mikesu.net/33/">
	
	<link rel="shortcut icon" href='/favicon.ico'  type="image/x-icon">
	<link rel="stylesheet" href="//cdn.jsdelivr.net/npm/normalize.css/normalize.min.css">
<link rel="stylesheet" href="//cdn.jsdelivr.net/npm/purecss/build/pure-min.min.css">
<link rel="stylesheet" href="//cdn.jsdelivr.net/npm/purecss/build/grids-responsive-min.css">
<link rel="stylesheet" href="//cdn.jsdelivr.net/npm/font-awesome@4.7.0/css/font-awesome.min.css">

<link rel="stylesheet" href="/css/style.min.css">
	
</head>
<body>
    <div class="body_container">
		<header id="header">
			<div class="site-name ">
	
	<a id="logo" href="/">Mike SU</a>
	<p class="description">Note &amp; Blog</p>
</div>
		    <nav id="nav-menu">
	<a class="" href="/">
		<i class="fa fa-home"> 首页</i>
	</a>
	
	<a  href="/archives/" title="归档">
		<i class='fa fa-archive'></i> 归档
	</a>
	
	<a  href="/about/" title="关于">
		<i class='fa fa-user'></i> 关于
	</a>
	
</nav>
		</header>
        <div id="layout" class="pure-g">
            <div class="pure-u-1 pure-u-md-3-4">
				<main class="content_container">
					
<article class="post">
	

	<h1 class="post-title">通过WebRTC实现网页间文件传输</h1>
	<div class="post-meta">
	2014年11月5日
	
	</div>
	<div class="post-content">
		<p>这里采用PeerJS作为Signaling服务器（mikesu.herokuapp.com)。</p>
<h2 id="接收方使用方法">接收方使用方法</h2>
<ol>
<li>调用connectPeerServer，连接PeerServer。</li>
<li>通过其他途径吧PeerId告诉发送方。</li>
<li>等待接收文件。</li>
</ol>
<h2 id="发送方使用方法">发送方使用方法</h2>
<ol>
<li>调用connectPeerServer，连接PeerServer。</li>
<li>拿到接收方的peerId和选择文件（使用Html5的FileAPI）通过sendFile发送文件</li>
</ol>
<h2 id="代码">代码</h2>
<div class="highlight"><pre style="background-color:#f0f3f3;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-js" data-lang="js"><span style="color:#069;font-weight:bold">var</span> peerServer;

<span style="color:#069;font-weight:bold">function</span> connectPeerServer(){
    <span style="color:#09f;font-style:italic">//连接Peer服务器
</span><span style="color:#09f;font-style:italic"></span>    peerServer <span style="color:#555">=</span> <span style="color:#069;font-weight:bold">new</span> Peer({<span style="color:#c30">&#39;host&#39;</span><span style="color:#555">:</span><span style="color:#c30">&#39;mikesu.herokuapp.com&#39;</span>, <span style="color:#c30">&#39;port&#39;</span><span style="color:#555">:</span> <span style="color:#f60">80</span>,<span style="color:#c30">&#39;debug&#39;</span><span style="color:#555">:</span><span style="color:#f60">3</span>});
    <span style="color:#09f;font-style:italic">//连接成功后显示peerId
</span><span style="color:#09f;font-style:italic"></span>    peerServer.on(<span style="color:#c30">&#39;open&#39;</span>,<span style="color:#069;font-weight:bold">function</span>(peerId){
        log(<span style="color:#c30">&#39;成功连接 PeerServer!&#39;</span>);
        log(<span style="color:#c30">&#39;PerrId: &#39;</span><span style="color:#555">+</span>peerId);
    });
    <span style="color:#09f;font-style:italic">//当有文件发送过来的时候触发receiveFile函数
</span><span style="color:#09f;font-style:italic"></span>    peerServer.on(<span style="color:#c30">&#39;connection&#39;</span>,receiveFile);
}


<span style="color:#069;font-weight:bold">function</span> receiveFile(connect){
    <span style="color:#09f;font-style:italic">//在连接里面包括了一下文件的元数据
</span><span style="color:#09f;font-style:italic"></span>    <span style="color:#069;font-weight:bold">var</span> fileName <span style="color:#555">=</span> connect.metadata.fileName;
    <span style="color:#069;font-weight:bold">var</span> fileSize <span style="color:#555">=</span> connect.metadata.fileSize;
    <span style="color:#069;font-weight:bold">var</span> lastModifieDate <span style="color:#555">=</span> connect.metadata.lastModifiedDate;
    log(<span style="color:#c30">&#39;收到文件接收请求：&#39;</span><span style="color:#555">+</span>fileName);
    <span style="color:#09f;font-style:italic">//连接可用触发
</span><span style="color:#09f;font-style:italic"></span>    connect.on(<span style="color:#c30">&#39;open&#39;</span>,<span style="color:#069;font-weight:bold">function</span>(){
        <span style="color:#09f;font-style:italic">//确认是否接收
</span><span style="color:#09f;font-style:italic"></span>        <span style="color:#069;font-weight:bold">var</span> result <span style="color:#555">=</span> confirm(<span style="color:#c30">&#39;Receive File:&#39;</span><span style="color:#555">+</span>fileName);
        log(<span style="color:#c30">&#39;是否接收：&#39;</span><span style="color:#555">+</span>result);
        <span style="color:#069;font-weight:bold">if</span>(result){
            <span style="color:#09f;font-style:italic">//这里用的了闭包哦～～～
</span><span style="color:#09f;font-style:italic"></span>            <span style="color:#09f;font-style:italic">//收到数据后通过downloadFile保存文件
</span><span style="color:#09f;font-style:italic"></span>            connect.on(<span style="color:#c30">&#39;data&#39;</span>,(<span style="color:#069;font-weight:bold">function</span>(f){
                <span style="color:#069;font-weight:bold">return</span> <span style="color:#069;font-weight:bold">function</span>(data){
                    log(<span style="color:#c30">&#39;接受到文件&#39;</span>);
                    downloadFile(f,data);
                }
            })(fileName));
            <span style="color:#09f;font-style:italic">//通知对方发生文件内容
</span><span style="color:#09f;font-style:italic"></span>            log(<span style="color:#c30">&#39;发送接收文件指令OK，&#39;</span>);
            connect.send(<span style="color:#c30">&#39;ok&#39;</span>);
        }<span style="color:#069;font-weight:bold">else</span>{
            <span style="color:#09f;font-style:italic">//通知对方不接收文件
</span><span style="color:#09f;font-style:italic"></span>            log(<span style="color:#c30">&#39;发送拒绝文件指令cancel&#39;</span>);
            connect.send(<span style="color:#c30">&#39;cancel&#39;</span>);
        }
    });
}

<span style="color:#069;font-weight:bold">function</span> downloadFile(fileName,data){
    log(<span style="color:#c30">&#39;下载文件&#39;</span>);
    <span style="color:#069;font-weight:bold">var</span> aLink <span style="color:#555">=</span> <span style="color:#366">document</span>.createElement(<span style="color:#c30">&#39;a&#39;</span>);
    <span style="color:#069;font-weight:bold">var</span> evt <span style="color:#555">=</span> <span style="color:#366">document</span>.createEvent(<span style="color:#c30">&#34;HTMLEvents&#34;</span>);
    evt.initEvent(<span style="color:#c30">&#34;click&#34;</span>, <span style="color:#069;font-weight:bold">false</span>, <span style="color:#069;font-weight:bold">false</span>);
    aLink.download <span style="color:#555">=</span> fileName;
    <span style="color:#069;font-weight:bold">var</span> blob <span style="color:#555">=</span> <span style="color:#069;font-weight:bold">new</span> Blob([data]);
    aLink.href <span style="color:#555">=</span> URL.createObjectURL(blob);
    aLink.dispatchEvent(evt);
}

<span style="color:#069;font-weight:bold">function</span> sendFile(file,peerId){
    <span style="color:#09f;font-style:italic">//构造连接元数据
</span><span style="color:#09f;font-style:italic"></span>    <span style="color:#069;font-weight:bold">var</span> fileMeta <span style="color:#555">=</span> {};
    fileMeta.fileName <span style="color:#555">=</span> file.name;
    fileMeta.fileSize <span style="color:#555">=</span> file.size;
    fileMeta.lastModifiedDate <span style="color:#555">=</span> file.lastModifiedDate.toDateString();
    <span style="color:#069;font-weight:bold">var</span> connectOption <span style="color:#555">=</span> {};
    connectOption.metadata <span style="color:#555">=</span> fileMeta;
    <span style="color:#09f;font-style:italic">//建立 DataChannel
</span><span style="color:#09f;font-style:italic"></span>    <span style="color:#069;font-weight:bold">var</span> connect <span style="color:#555">=</span> peerServer.connect(peerId,connectOption);
    connect.on(<span style="color:#c30">&#39;open&#39;</span>,<span style="color:#069;font-weight:bold">function</span>(){
        log(<span style="color:#c30">&#39;DataChannel 连接成功&#39;</span>);
        <span style="color:#09f;font-style:italic">//等待对方指令
</span><span style="color:#09f;font-style:italic"></span>        connect.on(<span style="color:#c30">&#39;data&#39;</span>,<span style="color:#069;font-weight:bold">function</span>(data){
            log(<span style="color:#c30">&#39;对方指令&#39;</span><span style="color:#555">+</span>data);
            <span style="color:#09f;font-style:italic">//对方接受传输
</span><span style="color:#09f;font-style:italic"></span>            <span style="color:#069;font-weight:bold">if</span>(data<span style="color:#555">==</span><span style="color:#c30">&#39;ok&#39;</span>){
                <span style="color:#069;font-weight:bold">var</span> reader <span style="color:#555">=</span> <span style="color:#069;font-weight:bold">new</span> FileReader();
                reader.onload <span style="color:#555">=</span> (<span style="color:#069;font-weight:bold">function</span>(e) {
                    log(<span style="color:#c30">&#39;sendFile 发送文件&#39;</span>);
                    connect.send(e.target.result);
                });
                reader.readAsArrayBuffer(file);
            }
            <span style="color:#09f;font-style:italic">//对方拒绝接收
</span><span style="color:#09f;font-style:italic"></span>            <span style="color:#069;font-weight:bold">else</span> <span style="color:#069;font-weight:bold">if</span>(data<span style="color:#555">==</span><span style="color:#c30">&#39;cancel&#39;</span>){
                log(<span style="color:#c30">&#39;对方取消接收&#39;</span>);
            }
            <span style="color:#09f;font-style:italic">//返回命令出错
</span><span style="color:#09f;font-style:italic"></span>            <span style="color:#069;font-weight:bold">else</span>{
                log(<span style="color:#c30">&#39;指令错误&#39;</span>);
            }
        });
    });
}
</code></pre></div>
	</div>
	
	
<div class="post-nav">
	
	
	<a class="pre" href="/32/">Boot2docker通过Samba实现文件夹共享</a>
	
	
	
	
	<a class="next" href="/34/">Java RMI远程调用简单示例</a>
	
	
</div>

	
<div class="post-archive">
    <ul class="post-copyright">
        <li><strong>原文作者：</strong><a rel="author" href="https://mikesu.net">Mike SU</a></li>
        <li style="word-break:break-all"><strong>原文链接：</strong><a href="https://mikesu.net/33/">https://mikesu.net/33/</a></li>
        <li><strong>版权声明：</strong>本作品采用<a rel="license" href="https://creativecommons.org/licenses/by/4.0/">署名 4.0 国际 (CC BY 4.0)</a>进行许可。</li>
    </ul>
</div>
<br/>


	

	
    

    
    
</article>

				</main>
            </div>
			<div class="pure-u-1-4 hidden_mid_and_down">
			    <div id="sidebar">
				    <section class="widget">
<form class="search-form" action='/search/' method="get" accept-charset="utf-8" _lpchecked="1">
      
      <input type="text" name="q" maxlength="20" placeholder="Search">
	  
</form>
</section>
					
					<section class="widget">
<h3 class="widget-title"><i class="fa fa-file-o"> 最近文章</i></h3>
<ul class="widget-list">
    
    <li>
        <a href="/35/" title="搭建 JavaScript 开发环境">搭建 JavaScript 开发环境</a>
    </li>
    
    <li>
        <a href="/34/" title="Java RMI远程调用简单示例">Java RMI远程调用简单示例</a>
    </li>
    
    <li>
        <a href="/33/" title="通过WebRTC实现网页间文件传输">通过WebRTC实现网页间文件传输</a>
    </li>
    
    <li>
        <a href="/32/" title="Boot2docker通过Samba实现文件夹共享">Boot2docker通过Samba实现文件夹共享</a>
    </li>
    
    <li>
        <a href="/31/" title="docker 使用代理连接 Docker Hub">docker 使用代理连接 Docker Hub</a>
    </li>
    
    <li>
        <a href="/30/" title="Boot2docker通过VirtualBox Guest Additions实现目录共享">Boot2docker通过VirtualBox Guest Additions实现目录共享</a>
    </li>
    
    <li>
        <a href="/29/" title="绿色版Solr安装配置">绿色版Solr安装配置</a>
    </li>
    
    <li>
        <a href="/28/" title="我的博客之路">我的博客之路</a>
    </li>
    
    <li>
        <a href="/27/" title="Pelican支持Swiftype搜索">Pelican支持Swiftype搜索</a>
    </li>
    
    <li>
        <a href="/26/" title="启用免费版MarkdownPad2的Markdown扩展模式">启用免费版MarkdownPad2的Markdown扩展模式</a>
    </li>
    
</ul>
</section>
					
					
				</div>
			</div>
			<div class="pure-u-1 pure-u-md-3-4">
				<footer id="footer">
					<div>
	Copyright &copy; 2021 <a href="https://mikesu.net">Mike SU</a>
	
</div>
<div>
	Powered by<a href="https://gohugo.io/" target="_black" rel="nofollow"> Hugo</a>
	Theme by<a href="https://github.com/tufu9441/maupassant-hexo" target="_black"> Maupassant</a>
</div>
<a id="rocket" href="#top"></a>
					<script type="text/javascript" src="//cdn.bootcdn.net/ajax/libs/jquery/3.4.1/jquery.min.js"></script>
<script type="text/javascript" src="/js/totop.js"></script>

					
	<script type="text/javascript" src="/js/toc.js"></script>

				</footer>
			</div>
        </div>
    </div>
</body>
</html>